package com.gitee.swsk33.websockethandlerdemo.handler.websocket;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import org.springframework.web.util.UriTemplate;

import java.util.Map;

/**
 * 简单的路径传参解析
 */
@Slf4j
@Component
public class PathWebSocketHandler implements WebSocketHandler {

	/**
	 * 用于获取路径参数中的参数值
	 *
	 * @param path         实际路径
	 * @param variableName 路径变量名
	 * @return 对应的路径变量的实际值
	 */
	private String getPathVariable(String path, String variableName) {
		// 传入路径模板
		UriTemplate template = new UriTemplate("/ws/path/{userId}");
		// 解析实际路径中的变量及其值
		Map<String, String> variables = template.match(path);
		// 返回对应路径变量值
		return variables.get(variableName);
	}

	/**
	 * 连接建立时执行的方法
	 *
	 * @param session WebSocket会话对象
	 */
	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		log.info("连接已建立！");
		TextMessage message = new TextMessage("连接成功！");
		session.sendMessage(message);
		// 先获取实际连接路径
		String path = session.getUri().getPath();
		// 解析路径变量
		log.info("路径参数userId为：{}", getPathVariable(path, "userId"));
	}

	/**
	 * 客户端发来消息时执行的方法
	 *
	 * @param session WebSocket会话对象
	 * @param message 客户端发来的消息对象
	 */
	@Override
	public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) {
		log.info("接收到客户端消息！");
	}

	/**
	 * 出现错误时的执行方法
	 *
	 * @param session   WebSocket会话对象
	 * @param exception 出现错误的异常
	 */
	@Override
	public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
		log.error("出现错误！{}", exception.getMessage());
		session.close();
	}

	/**
	 * 断开连接时执行的方法
	 *
	 * @param session     WebSocket会话对象
	 * @param closeStatus 断开连接的状态码
	 */
	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
		log.warn("与客户端断开连接！");
	}

	/**
	 * 是否支持部分消息
	 * 不用管保持默认即可
	 */
	@Override
	public boolean supportsPartialMessages() {
		return false;
	}

}